<script>
  // /*
  //   1
  //   转换秒数成为带格式的时间
  //     要求时间格式 时:分:秒
  //     不足两位的补0，比如1小时0分10秒：01:00:10
  // */

  function formatTime(second) {//?
    let n = second;
    let hour = Math.floor(n / 3600);//小时
    let last = n - hour * 3600;//转成小时之后剩余的秒数
    let minute = Math.floor(last / 60);//分
    last = last - minute * 60;
    let sec = Math.floor(last % 60);//转成分之后剩余的秒
    hour < 10 && (hour = "0" + hour);
    minute < 10 && (minute = "0" + minute);
    sec < 10 && (sec = "0" + sec);
    return hour + ":" + minute + ":" + sec

  }

  console.log(formatTime(3610)) // 01:00:10


  // /*
  //   2
  //   描述
  //   完成下面的函数使这段代码可以正常运行
  // */

  function speak(fn, obj) {
    return fn.apply(obj)
  }

  console.log(speak(function () { console.log(this.greeting + ', ' + this.name + '!!!'); }, { greeting: 'Hello', name: 'Rebecca' }
  )) // 打印 Hello, Rebecca!!!

  // /*
  //   3
  //   完成函数 createModule，调用之后满足如下要求：
  //   1、返回一个对象
  //   2、对象的 greeting 属性值等于 str1， name 属性值等于 str2
  //   3、对象存在一个 sayIt 方法，该方法返回的字符串为 greeting属性值 + ', ' + name属性值
  //   */
  // function createModule(str1, str2) {
  //   return {
  //     greeting: str1, name: str2, sayIt: () => {
  //       return `${this.greeting},${this.name}`
  //     }
  //   }

  // }
  // createModule('你好', '张三').sayIt()


  // /*
  //   4
  //   描述
  //   在数组 arr 中，查找值与 item 相等的元素出现的所有位置
  // */
  // function findAllOccurrences(arr, target) {
  //   // 可以尝试用reduce完成
  //   arr.reduce((a, b, index) => {
  //     if (b === target) {
  //       a.push(index)
  //     }
  //     return a
  //   }, [])

  // }
  // // test：
  // findAllOccurrences(['a', 'b', 'c', 'd', 'e', 'f', 'a', 'b', 'c'], 'a')
  // // [0, 6]


  // /*
  //   5
  //   描述
  //   找出数组 arr 中重复出现过的元素（不用考虑返回顺序）
  // */
  // function duplicates(arr) {
  //   // 可以尝试用reduce完成
  //   arr.reduce((a, b, index) => {
  //     if (arr.indexOf(b) !== arr.lastIndexOf(b) && a.indexOf(b) === -1) {
  //       a.push(b)
  //     }
  //     return a
  //   }, [])
  // }
  // // test：
  // duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3])
  // // [1, 3, 4]

  /*
    6
    写一个这样的函数，它可以缓存某函数的执行结果
    当localStorage中没有fn函数的执行结果时，直接执行fn，
      把它的返回结果存入localStorage
    当localStorage中有fn函数的执行结果时，直接返回结果

    观察localStorage中数据的变化
  */

  function cache(fn, ...args) {
    const key = stringifyFn(fn, ...args) // localStorage的key
    console.log("key = ", `"${key}"`)
    // 你的代码
    let value = JSON.parse(localStorage.getItem(key));
    if (value === null) {
      value = fn(...args)
      localStorage.setItem(key, JSON.stringify(value))
      return value
    } else {
      return value
    }
  }
  function stringifyFn(fn, ...args) {
    return `${fn.name}(...${JSON.stringify(args)})`
  }
  // 测试
  function bigloop(n) {
    for (let i = 0; i < n; i++) { }
    return n
  }
  function add(a, b) {
    return a + b
  }
  // 第一次运行
  console.log(cache(add, 101, 200))
  // 第二次运行用缓存返回
  console.log(cache(add, 101, 200))

  // 第一次运行，执行1亿次循环，速度较慢
  let start = Date.now()
  let v1 = cache(bigloop, 10e8)
  console.log(`耗时${Date.now() - start}ms`, `结果${v1}`)
  // 第二次运行，应该用缓存返回，速度很快
  start = Date.now()
  let v2 = cache(bigloop, 10e8)
  console.log(`耗时${Date.now() - start}ms`, `结果${v2}`)

</script>